package ch.netcetera.planningpoker.server.dao;

import java.util.List;
import java.util.logging.Logger;

import ch.netcetera.planningpoker.server.ChannelMessageSender;
import ch.netcetera.planningpoker.server.model.Game;
import ch.netcetera.planningpoker.server.model.Participant;
import ch.netcetera.planningpoker.shared.ui.events.GameUiEvent;

import com.google.appengine.api.channel.ChannelService;
import com.google.appengine.api.channel.ChannelServiceFactory;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.googlecode.objectify.Key;

public class ParticipantDao extends ObjectifyDao<Participant> {

    private static final Logger logger = Logger.getLogger(ParticipantDao.class
            .getName());

    private GameDao gameDao = new GameDao();
    private ChannelMessageSender channelMsgSender = new ChannelMessageSender();

    public Participant createDistinctParticipant(String name, Long gameId)
            throws EntityNotFoundException {

        Key<Game> gameKey = gameDao.getKey(gameId);

        Participant participant = new Participant();
        participant.setName(name);
        participant.setGame(gameKey);

        Participant byExample = getByExample(participant);

        // looping until we find a uniqe username.. may be a bad idea ;-)
        int i = 1;
        while (byExample != null) {
            participant.setName(name + "_" + i);
            byExample = getByExample(participant);
            i++;
        }

        // reload participant, to get generated id
        Key<Participant> participantKey = put(participant);
        participant = get(participantKey);

        // generate channel token and persist again (find a nicer solution one day.. 
        ChannelService channelService = ChannelServiceFactory
                .getChannelService();
        String channelToken = channelService.createChannel(participantKey
                .getId() + "");
        participant.setChannelToken(channelToken);

        put(participant);

        // send message to all clients
        channelMsgSender.sendGameRelatedEvent(GameUiEvent.UserListChanged, gameId);

        return participant;

    }

    public List<Participant> getParticipantsForGame(Long gameId) {

        Key<Game> gameKey = gameDao.getKey(gameId);

        Participant queryParams = new Participant();
        queryParams.setGame(gameKey);

        return listByExample(queryParams);

    }

    public void removeParticipantFromGame(Long participantId) throws EntityNotFoundException {
        Key<Participant> participantKey = getKey(participantId);
        
        Participant participant = get(participantKey);
        Long gameId = participant.getGameId();
        
        // TODO shouldn't we just flag the participant?
        deleteKey(participantKey);
        
        // send message to all clients
        channelMsgSender.sendGameRelatedEvent(GameUiEvent.UserListChanged, gameId);
    }

}
